package cn.wjssl.domain.credit.service;

import cn.wjssl.domain.award.model.valobj.TaskStateVO;
import cn.wjssl.domain.credit.event.CreditAdjustSuccessMessageEvent;
import cn.wjssl.domain.credit.model.aggregate.TradeAggregate;
import cn.wjssl.domain.credit.model.entity.CreditAccountEntity;
import cn.wjssl.domain.credit.model.entity.CreditOrderEntity;
import cn.wjssl.domain.credit.model.entity.TaskEntity;
import cn.wjssl.domain.credit.model.entity.TradeEntity;
import cn.wjssl.domain.credit.repository.ICreditRepository;
import cn.wjssl.types.event.BaseEvent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 积分调额实现类
 */
@Slf4j
@Service
public class CreditAdjustService implements ICreditAdjustService {

    @Resource
    private ICreditRepository repository;

    @Resource
    private CreditAdjustSuccessMessageEvent creditAdjustSuccessMessageEvent;

    /**
     * 创建积分调额订单
     * 根据 tradeEntity中的amount的正负, 对积分账户进行增加或者扣减
     * 如果是支付订单, 那么就是扣减积分
     * 如果是签到返利, 那么就是增加积分
     * 发送mq消息, 推送积分调额成功mq, 监听将支付订单(sku单)的状态变为completed
     * @param tradeEntity 交易实体对象
     * @return 单号
     */
    @Override
    public String createCreditOrder(TradeEntity tradeEntity) {
        log.info("增加账户积分额度开始 userId:{} tradeName:{} amount:{}", tradeEntity.getUserId(), tradeEntity.getTradeName(), tradeEntity.getAmount());

        // 1. 构建积分账户实体
        CreditAccountEntity creditAccountEntity = CreditAccountEntity.builder()
                .userId(tradeEntity.getUserId())
                .adjustAmount(tradeEntity.getAmount())
                .build();

        // 2. 构建积分操作订单实体
        CreditOrderEntity creditOrderEntity = CreditOrderEntity.builder()
                .userId(tradeEntity.getUserId())
                .tradeName(tradeEntity.getTradeName())
                .tradeType(tradeEntity.getTradeType())
                .orderId(RandomStringUtils.randomNumeric(12))
                .tradeAmount(tradeEntity.getAmount())
                .outBusinessNo(tradeEntity.getOutBusinessNo())
                .build();

        // 3. 构建消息体, sku单详情
        CreditAdjustSuccessMessageEvent.CreditAdjustSuccessMessage creditAdjustSuccessMessage = new CreditAdjustSuccessMessageEvent.CreditAdjustSuccessMessage();
        creditAdjustSuccessMessage.setUserId(tradeEntity.getUserId());
        creditAdjustSuccessMessage.setOrderId(creditOrderEntity.getOrderId());
        creditAdjustSuccessMessage.setAmount(tradeEntity.getAmount());
        creditAdjustSuccessMessage.setOutBusinessNo(tradeEntity.getOutBusinessNo());
        BaseEvent.EventMessage<CreditAdjustSuccessMessageEvent.CreditAdjustSuccessMessage> sendMsg = creditAdjustSuccessMessageEvent.buildEventMessage(creditAdjustSuccessMessage);

        TaskEntity taskEntity = TaskEntity.builder()
                .userId(tradeEntity.getUserId())
                .topic(creditAdjustSuccessMessageEvent.topic())
                .messageId(sendMsg.getId())
                .message(sendMsg)
                .state(TaskStateVO.create)
                .build();

        // 4. 构建聚合对象
        TradeAggregate aggregate = TradeAggregate.builder()
                .userId(tradeEntity.getUserId())
                .creditAccountEntity(creditAccountEntity)
                .creditOrderEntity(creditOrderEntity)
                .taskEntity(taskEntity)
                .build();

        // 4. 事务保存积分交易订单, 更新账户积分, 推送积分调额成功mq
        repository.saveUserCreditTradeOrder(aggregate);
        log.info("增加账户积分额度完成 userId:{} orderId:{}", tradeEntity.getUserId(), creditOrderEntity.getOrderId());

        // 5. 返回订单Id
        return creditOrderEntity.getOrderId();
    }

    // 根据 userId  查询积分账户余额
    @Override
    public CreditAccountEntity queryUserCreditAccount(String userId) {
        return repository.queryUserCreditAccount(userId);
    }
}
